"""
告警管理系统API端点
提供告警规则管理、告警事件处理、工作流操作和统计查询的REST API接口
"""
from datetime import datetime, timedelta
from typing import List, Dict, Optional, Any
from fastapi import APIRouter, HTTPException, Depends, Query, Body
from fastapi.responses import JSONResponse

from schemas.alert_management import (
    AlertRule, AlertEvent, AlertRuleCreateRequest, AlertRuleUpdateRequest,
    AlertEventUpdateRequest, AlertQuery, AlertStatistics, NotificationTemplate,
    NotificationConfig, AlertLevel, AlertCategory, AlertStatus, AlertResponse
)
from services.alerts.alert_management_service import AlertManagementService

router = APIRouter(prefix="/alert-management", tags=["告警管理"])

# 全局服务实例
alert_service = AlertManagementService()


async def get_alert_service() -> AlertManagementService:
    """获取告警管理服务实例"""
    return alert_service


@router.on_event("startup")
async def startup_alert_service():
    """启动告警管理服务"""
    await alert_service.start_service()
    await alert_service.setup_default_templates()
    await alert_service.setup_default_configs()


@router.on_event("shutdown")
async def shutdown_alert_service():
    """关闭告警管理服务"""
    await alert_service.stop_service()


# ==================== 告警规则管理 ====================

@router.post("/rules", response_model=AlertRule, summary="创建告警规则")
async def create_alert_rule(
    rule_request: AlertRuleCreateRequest,
    service: AlertManagementService = Depends(get_alert_service)
):
    """创建新的告警规则"""
    try:
        rule = await service.create_alert_rule(rule_request)
        return rule
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"创建告警规则失败: {str(e)}")


@router.get("/rules", response_model=List[AlertRule], summary="获取告警规则列表")
async def list_alert_rules(
    category: Optional[AlertCategory] = Query(None, description="告警类别过滤"),
    enabled_only: bool = Query(True, description="仅显示启用的规则"),
    service: AlertManagementService = Depends(get_alert_service)
):
    """获取告警规则列表"""
    try:
        rules = await service.list_alert_rules(category, enabled_only)
        return rules
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取告警规则列表失败: {str(e)}")


@router.get("/rules/{rule_id}", response_model=AlertRule, summary="获取告警规则详情")
async def get_alert_rule(
    rule_id: str,
    service: AlertManagementService = Depends(get_alert_service)
):
    """获取指定告警规则的详情"""
    try:
        rule = await service.get_alert_rule(rule_id)
        if not rule:
            raise HTTPException(status_code=404, detail="告警规则不存在")
        return rule
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取告警规则失败: {str(e)}")


@router.put("/rules/{rule_id}", response_model=AlertRule, summary="更新告警规则")
async def update_alert_rule(
    rule_id: str,
    rule_request: AlertRuleUpdateRequest,
    service: AlertManagementService = Depends(get_alert_service)
):
    """更新指定的告警规则"""
    try:
        rule = await service.update_alert_rule(rule_id, rule_request)
        if not rule:
            raise HTTPException(status_code=404, detail="告警规则不存在")
        return rule
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"更新告警规则失败: {str(e)}")


@router.delete("/rules/{rule_id}", response_model=AlertResponse, summary="删除告警规则")
async def delete_alert_rule(
    rule_id: str,
    service: AlertManagementService = Depends(get_alert_service)
):
    """删除指定的告警规则"""
    try:
        success = await service.delete_alert_rule(rule_id)
        if not success:
            raise HTTPException(status_code=404, detail="告警规则不存在")
        
        return AlertResponse(
            success=True,
            message="告警规则删除成功"
        )
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"删除告警规则失败: {str(e)}")


# ==================== 告警事件管理 ====================

@router.post("/process-data", response_model=List[AlertEvent], summary="处理数据并生成告警")
async def process_data(
    data: Dict[str, Any] = Body(..., description="待处理的数据"),
    service: AlertManagementService = Depends(get_alert_service)
):
    """处理输入数据并根据规则生成告警"""
    try:
        alerts = await service.process_data(data)
        return alerts
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"处理数据失败: {str(e)}")


@router.get("/alerts", response_model=List[AlertEvent], summary="查询告警列表")
async def query_alerts(
    alert_ids: Optional[str] = Query(None, description="告警ID列表(逗号分隔)"),
    rule_ids: Optional[str] = Query(None, description="规则ID列表(逗号分隔)"),
    categories: Optional[str] = Query(None, description="告警类别列表(逗号分隔)"),
    levels: Optional[str] = Query(None, description="告警级别列表(逗号分隔)"),
    statuses: Optional[str] = Query(None, description="告警状态列表(逗号分隔)"),
    location: Optional[str] = Query(None, description="位置"),
    camera_id: Optional[str] = Query(None, description="摄像头ID"),
    classroom_id: Optional[str] = Query(None, description="教室ID"),
    teacher_id: Optional[str] = Query(None, description="教师ID"),
    assigned_to: Optional[str] = Query(None, description="分配给"),
    tags: Optional[str] = Query(None, description="标签列表(逗号分隔)"),
    start_time: Optional[datetime] = Query(None, description="开始时间"),
    end_time: Optional[datetime] = Query(None, description="结束时间"),
    limit: int = Query(100, description="返回数量限制"),
    offset: int = Query(0, description="偏移量"),
    service: AlertManagementService = Depends(get_alert_service)
):
    """查询告警列表"""
    try:
        # 构建查询条件
        query = AlertQuery(
            alert_ids=alert_ids.split(',') if alert_ids else None,
            rule_ids=rule_ids.split(',') if rule_ids else None,
            categories=[AlertCategory(c.strip()) for c in categories.split(',')] if categories else None,
            levels=[AlertLevel(l.strip()) for l in levels.split(',')] if levels else None,
            statuses=[AlertStatus(s.strip()) for s in statuses.split(',')] if statuses else None,
            location=location,
            camera_id=camera_id,
            classroom_id=classroom_id,
            teacher_id=teacher_id,
            assigned_to=assigned_to,
            tags=tags.split(',') if tags else None,
            start_time=start_time,
            end_time=end_time,
            limit=limit,
            offset=offset
        )
        
        alerts = await service.query_alerts(query)
        return alerts
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"查询告警失败: {str(e)}")


@router.get("/alerts/{alert_id}", response_model=AlertEvent, summary="获取告警详情")
async def get_alert(
    alert_id: str,
    service: AlertManagementService = Depends(get_alert_service)
):
    """获取指定告警的详情"""
    try:
        alert = await service.get_alert(alert_id)
        if not alert:
            raise HTTPException(status_code=404, detail="告警不存在")
        return alert
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取告警详情失败: {str(e)}")


@router.put("/alerts/{alert_id}", response_model=AlertResponse, summary="更新告警")
async def update_alert(
    alert_id: str,
    update_request: AlertEventUpdateRequest,
    user_id: str = Query(..., description="操作用户ID"),
    service: AlertManagementService = Depends(get_alert_service)
):
    """更新指定告警的信息"""
    try:
        success = await service.update_alert(alert_id, update_request, user_id)
        if not success:
            raise HTTPException(status_code=404, detail="告警不存在或更新失败")
        
        return AlertResponse(
            success=True,
            message="告警更新成功"
        )
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"更新告警失败: {str(e)}")


# ==================== 告警工作流操作 ====================

@router.post("/alerts/{alert_id}/assign", response_model=AlertResponse, summary="分配告警")
async def assign_alert(
    alert_id: str,
    assignee: str = Body(..., description="分配给的用户ID"),
    user_id: str = Query(..., description="操作用户ID"),
    service: AlertManagementService = Depends(get_alert_service)
):
    """分配告警给指定用户"""
    try:
        success = await service.assign_alert(alert_id, assignee, user_id)
        if not success:
            raise HTTPException(status_code=404, detail="告警不存在或分配失败")
        
        return AlertResponse(
            success=True,
            message=f"告警已分配给 {assignee}"
        )
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"分配告警失败: {str(e)}")


@router.post("/alerts/{alert_id}/acknowledge", response_model=AlertResponse, summary="确认告警")
async def acknowledge_alert(
    alert_id: str,
    user_id: str = Query(..., description="操作用户ID"),
    note: Optional[str] = Body(None, description="确认备注"),
    service: AlertManagementService = Depends(get_alert_service)
):
    """确认告警"""
    try:
        success = await service.acknowledge_alert(alert_id, user_id, note)
        if not success:
            raise HTTPException(status_code=404, detail="告警不存在或确认失败")
        
        return AlertResponse(
            success=True,
            message="告警已确认"
        )
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"确认告警失败: {str(e)}")


@router.post("/alerts/{alert_id}/resolve", response_model=AlertResponse, summary="解决告警")
async def resolve_alert(
    alert_id: str,
    resolution_note: str = Body(..., description="解决备注"),
    user_id: str = Query(..., description="操作用户ID"),
    service: AlertManagementService = Depends(get_alert_service)
):
    """解决告警"""
    try:
        success = await service.resolve_alert(alert_id, user_id, resolution_note)
        if not success:
            raise HTTPException(status_code=404, detail="告警不存在或解决失败")
        
        return AlertResponse(
            success=True,
            message="告警已解决"
        )
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"解决告警失败: {str(e)}")


@router.post("/alerts/{alert_id}/close", response_model=AlertResponse, summary="关闭告警")
async def close_alert(
    alert_id: str,
    user_id: str = Query(..., description="操作用户ID"),
    close_note: Optional[str] = Body(None, description="关闭备注"),
    service: AlertManagementService = Depends(get_alert_service)
):
    """关闭告警"""
    try:
        success = await service.close_alert(alert_id, user_id, close_note)
        if not success:
            raise HTTPException(status_code=404, detail="告警不存在或关闭失败")
        
        return AlertResponse(
            success=True,
            message="告警已关闭"
        )
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"关闭告警失败: {str(e)}")


@router.post("/alerts/{alert_id}/escalate", response_model=AlertResponse, summary="升级告警")
async def escalate_alert(
    alert_id: str,
    escalation_target: str = Body(..., description="升级目标用户ID"),
    escalation_reason: str = Body(..., description="升级原因"),
    user_id: str = Query(..., description="操作用户ID"),
    service: AlertManagementService = Depends(get_alert_service)
):
    """升级告警"""
    try:
        success = await service.escalate_alert(alert_id, escalation_target, user_id, escalation_reason)
        if not success:
            raise HTTPException(status_code=404, detail="告警不存在或升级失败")
        
        return AlertResponse(
            success=True,
            message=f"告警已升级给 {escalation_target}"
        )
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"升级告警失败: {str(e)}")


@router.post("/alerts/{alert_id}/reopen", response_model=AlertResponse, summary="重新打开告警")
async def reopen_alert(
    alert_id: str,
    reopen_reason: str = Body(..., description="重新打开原因"),
    user_id: str = Query(..., description="操作用户ID"),
    service: AlertManagementService = Depends(get_alert_service)
):
    """重新打开告警"""
    try:
        success = await service.reopen_alert(alert_id, user_id, reopen_reason)
        if not success:
            raise HTTPException(status_code=404, detail="告警不存在或重新打开失败")
        
        return AlertResponse(
            success=True,
            message="告警已重新打开"
        )
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"重新打开告警失败: {str(e)}")


@router.post("/alerts/{alert_id}/comment", response_model=AlertResponse, summary="添加告警评论")
async def add_alert_comment(
    alert_id: str,
    comment: str = Body(..., description="评论内容"),
    user_id: str = Query(..., description="操作用户ID"),
    service: AlertManagementService = Depends(get_alert_service)
):
    """添加告警评论"""
    try:
        success = await service.add_alert_comment(alert_id, user_id, comment)
        if not success:
            raise HTTPException(status_code=404, detail="告警不存在")
        
        return AlertResponse(
            success=True,
            message="评论已添加"
        )
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"添加评论失败: {str(e)}")


# ==================== 批量操作 ====================

@router.post("/alerts/bulk-assign", response_model=Dict[str, bool], summary="批量分配告警")
async def bulk_assign_alerts(
    alert_ids: List[str] = Body(..., description="告警ID列表"),
    assignee: str = Body(..., description="分配给的用户ID"),
    user_id: str = Query(..., description="操作用户ID"),
    service: AlertManagementService = Depends(get_alert_service)
):
    """批量分配告警"""
    try:
        results = await service.bulk_assign_alerts(alert_ids, assignee, user_id)
        return results
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"批量分配告警失败: {str(e)}")


@router.post("/alerts/bulk-resolve", response_model=Dict[str, bool], summary="批量解决告警")
async def bulk_resolve_alerts(
    alert_ids: List[str] = Body(..., description="告警ID列表"),
    resolution_note: str = Body(..., description="解决备注"),
    user_id: str = Query(..., description="操作用户ID"),
    service: AlertManagementService = Depends(get_alert_service)
):
    """批量解决告警"""
    try:
        results = await service.bulk_resolve_alerts(alert_ids, user_id, resolution_note)
        return results
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"批量解决告警失败: {str(e)}")


@router.post("/alerts/bulk-close", response_model=Dict[str, bool], summary="批量关闭告警")
async def bulk_close_alerts(
    alert_ids: List[str] = Body(..., description="告警ID列表"),
    user_id: str = Query(..., description="操作用户ID"),
    close_note: Optional[str] = Body(None, description="关闭备注"),
    service: AlertManagementService = Depends(get_alert_service)
):
    """批量关闭告警"""
    try:
        results = await service.bulk_close_alerts(alert_ids, user_id, close_note)
        return results
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"批量关闭告警失败: {str(e)}")


# ==================== 统计和报表 ====================

@router.get("/statistics", response_model=AlertStatistics, summary="获取告警统计")
async def get_alert_statistics(
    start_time: Optional[datetime] = Query(None, description="开始时间"),
    end_time: Optional[datetime] = Query(None, description="结束时间"),
    service: AlertManagementService = Depends(get_alert_service)
):
    """获取告警统计信息"""
    try:
        stats = await service.get_alert_statistics(start_time, end_time)
        return stats
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取告警统计失败: {str(e)}")


@router.get("/dashboard", response_model=Dict[str, Any], summary="获取仪表板数据")
async def get_dashboard_data(
    service: AlertManagementService = Depends(get_alert_service)
):
    """获取告警管理仪表板数据"""
    try:
        dashboard_data = await service.get_dashboard_data()
        return dashboard_data
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取仪表板数据失败: {str(e)}")


@router.get("/performance", response_model=Dict[str, Any], summary="获取性能指标")
async def get_performance_metrics(
    service: AlertManagementService = Depends(get_alert_service)
):
    """获取告警管理系统性能指标"""
    try:
        metrics = await service.get_performance_metrics()
        return metrics
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取性能指标失败: {str(e)}")


# ==================== 通知管理 ====================

@router.post("/notification-templates", response_model=AlertResponse, summary="添加通知模板")
async def add_notification_template(
    template: NotificationTemplate,
    service: AlertManagementService = Depends(get_alert_service)
):
    """添加通知模板"""
    try:
        await service.add_notification_template(template)
        return AlertResponse(
            success=True,
            message="通知模板添加成功"
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"添加通知模板失败: {str(e)}")


@router.post("/notification-configs", response_model=AlertResponse, summary="添加通知配置")
async def add_notification_config(
    config: NotificationConfig,
    service: AlertManagementService = Depends(get_alert_service)
):
    """添加通知配置"""
    try:
        await service.add_notification_config(config)
        return AlertResponse(
            success=True,
            message="通知配置添加成功"
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"添加通知配置失败: {str(e)}")


# ==================== 系统配置 ====================

@router.post("/configure/email", response_model=AlertResponse, summary="配置邮件通知")
async def configure_email_notifications(
    smtp_host: str = Body(..., description="SMTP服务器地址"),
    smtp_port: int = Body(..., description="SMTP端口"),
    username: str = Body(..., description="用户名"),
    password: str = Body(..., description="密码"),
    use_tls: bool = Body(True, description="是否使用TLS"),
    service: AlertManagementService = Depends(get_alert_service)
):
    """配置邮件通知"""
    try:
        service.configure_email_notifications(smtp_host, smtp_port, username, password, use_tls)
        return AlertResponse(
            success=True,
            message="邮件通知配置成功"
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"配置邮件通知失败: {str(e)}")


@router.post("/configure/sms", response_model=AlertResponse, summary="配置短信通知")
async def configure_sms_notifications(
    api_url: str = Body(..., description="短信API地址"),
    api_key: str = Body(..., description="API密钥"),
    api_secret: str = Body(..., description="API密码"),
    service: AlertManagementService = Depends(get_alert_service)
):
    """配置短信通知"""
    try:
        service.configure_sms_notifications(api_url, api_key, api_secret)
        return AlertResponse(
            success=True,
            message="短信通知配置成功"
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"配置短信通知失败: {str(e)}")


@router.post("/configure/webhook", response_model=AlertResponse, summary="配置Webhook通知")
async def configure_webhook_notifications(
    service: AlertManagementService = Depends(get_alert_service)
):
    """配置Webhook通知"""
    try:
        service.configure_webhook_notifications()
        return AlertResponse(
            success=True,
            message="Webhook通知配置成功"
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"配置Webhook通知失败: {str(e)}")


@router.post("/configure/websocket", response_model=AlertResponse, summary="配置WebSocket通知")
async def configure_websocket_notifications(
    service: AlertManagementService = Depends(get_alert_service)
):
    """配置WebSocket通知"""
    try:
        service.configure_websocket_notifications()
        return AlertResponse(
            success=True,
            message="WebSocket通知配置成功"
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"配置WebSocket通知失败: {str(e)}")


@router.post("/configure/mobile-push", response_model=AlertResponse, summary="配置移动推送通知")
async def configure_mobile_push_notifications(
    push_service_url: str = Body(..., description="推送服务地址"),
    app_key: str = Body(..., description="应用密钥"),
    app_secret: str = Body(..., description="应用密码"),
    service: AlertManagementService = Depends(get_alert_service)
):
    """配置移动推送通知"""
    try:
        service.configure_mobile_push_notifications(push_service_url, app_key, app_secret)
        return AlertResponse(
            success=True,
            message="移动推送通知配置成功"
        )
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"配置移动推送通知失败: {str(e)}")